package com.och.mrcp.service;

import com.och.mrcp.config.EngineConfig;
import com.och.mrcp.core.mrcp.factory.MrcpMessageFactory;
import com.och.mrcp.core.mrcp.model.MrcpEvent;
import com.och.mrcp.core.mrcp.model.MrcpRequest;
import com.och.mrcp.handler.MrcpMessageHandler;
import com.och.mrcp.handler.MrcpMessageSender;
import com.och.mrcp.model.RecognitionResult;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 统一语音会话管理器
 * 根据配置选择不同的语音服务提供商，提供统一的会话管理接口
 */
@Slf4j
@Service
public class UnifiedVoiceSessionManager {

    @Autowired
    private EngineConfig engineConfig;
    
    @Autowired
    private MrcpMessageSender mrcpMessageSender;
    
    @Lazy
    @Autowired
    private MrcpMessageHandler mrcpMessageHandler;
    
    // 提供商名称 -> 服务实现 的策略映射
    private final ConcurrentHashMap<String, VoiceSessionService> providerServiceMap = new ConcurrentHashMap<>();

    @Autowired
    public UnifiedVoiceSessionManager(List<VoiceSessionService> services) {
        if (services != null) {
            for (VoiceSessionService service : services) {
                try {
                    String name = service.getProviderName();
                    if (name != null && !name.trim().isEmpty()) {
                        providerServiceMap.put(name.toLowerCase(), service);
                    }
                } catch (Exception ignored) {}
            }
        }
    }

    // 可以在这里添加其他语音服务提供商
    // @Autowired
    // @Qualifier("tencentVoiceSessionService")
    // private VoiceSessionService tencentVoiceSessionService;
    
    // 会话ID到服务提供商的映射
    private final ConcurrentHashMap<String, String> sessionProviderMap = new ConcurrentHashMap<>();
    
    // 会话ID到MRCP请求的映射，用于发送事件时获取原始请求信息
    private final ConcurrentHashMap<String, MrcpRequest> sessionMrcpRequestMap = new ConcurrentHashMap<>();
    
    @PostConstruct
    public void init() {
        log.info("Initialized Unified Voice Session Manager with default provider: {}", engineConfig.getDefaultProvider());
    }
    
    /**
     * 创建语音识别会话（包含MRCP请求信息）
     * @param sessionId 会话ID
     * @param config 识别配置
     * @param callback 结果回调
     * @param provider 指定的服务提供商（可选，不指定则使用默认）
     * @param mrcpRequest 原始MRCP请求（用于发送事件）
     * @return 创建结果
     */
    public CompletableFuture<Void> createRecognitionSession(String sessionId, 
                                                           EngineConfig.RecognitionConfig config, 
                                                           VoiceSessionService.SessionCallback callback,
                                                           String provider,
                                                           MrcpRequest mrcpRequest) {
        
        String actualProvider = provider != null ? provider : engineConfig.getDefaultProvider();
        
        log.info("Creating recognition session: {} with provider: {}", sessionId, actualProvider);
        
        VoiceSessionService voiceSessionService = getVoiceSessionService(actualProvider);
        log.info("UnifiedVoiceSessionManager: Retrieved voiceSessionService: {} for provider: {}", 
                voiceSessionService != null ? voiceSessionService.getClass().getSimpleName() : "null", actualProvider);
        
        if (voiceSessionService == null) {
            log.error("UnifiedVoiceSessionManager: Failed to get voice service for provider: {}", actualProvider);
            return CompletableFuture.failedFuture(
                new IllegalArgumentException("Unsupported voice service provider: " + actualProvider));
        }
        
        log.info("UnifiedVoiceSessionManager: About to call createRecognitionSession on {}", 
                voiceSessionService.getClass().getSimpleName());
        
        // 存储MRCP请求信息
        if (mrcpRequest != null) {
            sessionMrcpRequestMap.put(sessionId, mrcpRequest);
        }
        
        // 包装回调以添加统一管理功能和MRCP事件发送
        VoiceSessionService.SessionCallback wrappedCallback = createWrappedCallback(sessionId, callback, actualProvider, mrcpRequest);
        
        // 记录会话映射
        log.info("UnifiedVoiceSessionManager: Storing session mapping - sessionId: {}, provider: {}", 
                sessionId, actualProvider);
        sessionProviderMap.put(sessionId, actualProvider);
        log.info("UnifiedVoiceSessionManager: sessionProviderMap now contains: {}", sessionProviderMap.keySet());
        
        return voiceSessionService.createRecognitionSession(sessionId, config, wrappedCallback)
            .whenComplete((result, throwable) -> {
                if (throwable != null) {
                    log.error("UnifiedVoiceSessionManager: Session creation failed for {}, cleaning up mappings", sessionId, throwable);
                    // 创建失败时清理映射
                    sessionProviderMap.remove(sessionId);
                    sessionMrcpRequestMap.remove(sessionId);
                } else {
                    log.info("UnifiedVoiceSessionManager: Session creation succeeded for {}", sessionId);
                }
            });
    }
    
    /**
     * 创建语音识别会话
     * @param sessionId 会话ID
     * @param config 识别配置
     * @param callback 结果回调
     * @param provider 指定的服务提供商（可选，不指定则使用默认）
     * @return 创建结果
     */
    public CompletableFuture<Void> createRecognitionSession(String sessionId, 
                                                           EngineConfig.RecognitionConfig config, 
                                                           VoiceSessionService.SessionCallback callback,
                                                           String provider) {
        return createRecognitionSession(sessionId, config, callback, provider, null);
    }
    
    /**
     * 创建语音识别会话（使用默认提供商）
     */
    public CompletableFuture<Void> createRecognitionSession(String sessionId, 
                                                           EngineConfig.RecognitionConfig config, 
                                                           VoiceSessionService.SessionCallback callback) {
        return createRecognitionSession(sessionId, config, callback, null);
    }
    
    /**
     * 启动语音识别会话
     */
    public CompletableFuture<Void> startRecognitionSession(String sessionId) {
        VoiceSessionService service = getSessionService(sessionId);
        if (service == null) {
            return CompletableFuture.failedFuture(
                new IllegalArgumentException("Session not found: " + sessionId));
        }
        
        return service.startRecognitionSession(sessionId);
    }
    
    /**
     * 发送音频数据到会话
     */
    public CompletableFuture<Void> sendAudioData(String sessionId, byte[] audioData) {
        log.debug("Attempting to send audio data for session: {}, data size: {}", 
                sessionId, audioData != null ? audioData.length : "null");
        
        // 验证音频数据
        if (audioData == null) {
            log.warn("UnifiedVoiceSessionManager: Received null audio data for session: {}", sessionId);
            return CompletableFuture.completedFuture(null);
        }
        
        if (audioData.length == 0) {
            log.debug("UnifiedVoiceSessionManager: Received empty audio data for session: {}", sessionId);
            return CompletableFuture.completedFuture(null);
        }
        
        VoiceSessionService service = getSessionService(sessionId);
        if (service == null) {
            log.warn("Cannot send audio data, session not found: {}", sessionId);
            log.warn("Available sessions in provider map: {}", sessionProviderMap.keySet());
            return CompletableFuture.completedFuture(null);
        }
        
        log.debug("Found service for session {}, sending audio data", sessionId);
        return service.sendAudioData(sessionId, audioData);
    }
    
    /**
     * 停止语音识别会话
     */
    public CompletableFuture<Void> stopRecognitionSession(String sessionId) {
        VoiceSessionService service = getSessionService(sessionId);
        if (service == null) {
            log.debug("Session not found for stop: {}", sessionId);
            return CompletableFuture.completedFuture(null);
        }
        
        return service.stopRecognitionSession(sessionId);
    }
    
    /**
     * 销毁语音识别会话
     */
    public CompletableFuture<Void> destroyRecognitionSession(String sessionId) {
        VoiceSessionService service = getSessionService(sessionId);
        
        // 清理映射
        String provider = sessionProviderMap.remove(sessionId);
        sessionMrcpRequestMap.remove(sessionId);
        
        if (service == null) {
            log.debug("Session not found for destroy: {}", sessionId);
            return CompletableFuture.completedFuture(null);
        }
        
        log.info("Destroying recognition session: {} from provider: {}", sessionId, provider);
        return service.destroyRecognitionSession(sessionId);
    }
    
    /**
     * 获取会话状态
     */
    public VoiceSessionService.SessionState getSessionState(String sessionId) {
        VoiceSessionService service = getSessionService(sessionId);
        return service != null ? service.getSessionState(sessionId) : null;
    }
    
    /**
     * 检查会话是否存在
     */
    public boolean sessionExists(String sessionId) {
        return sessionProviderMap.containsKey(sessionId);
    }
    
    /**
     * 获取指定提供商的活跃会话数量
     */
    public int getActiveSessionCount(String provider) {
        VoiceSessionService service = getVoiceSessionService(provider);
        return service != null ? service.getActiveSessionCount() : 0;
    }
    
    /**
     * 获取总的活跃会话数量
     */
    public int getTotalActiveSessionCount() {
        return providerServiceMap.values().stream().mapToInt(VoiceSessionService::getActiveSessionCount).sum();
    }
    
    /**
     * 清理所有会话
     */
    public void cleanupAllSessions() {
        log.info("Cleaning up all voice sessions across all providers");
        
        sessionProviderMap.clear();
        sessionMrcpRequestMap.clear();
        
        providerServiceMap.values().forEach(service -> {
            try {
                service.cleanupAllSessions();
            } catch (Exception e) {
                log.warn("Error cleaning up provider {}", service.getProviderName(), e);
            }
        });
        
        log.info("All voice sessions cleaned up");
    }
    
    /**
     * 获取会话对应的服务实例
     */
    private VoiceSessionService getSessionService(String sessionId) {
        log.info("UnifiedVoiceSessionManager: Getting service for session: {}", sessionId);
        log.info("UnifiedVoiceSessionManager: sessionProviderMap contains: {}", sessionProviderMap);
        
        String provider = sessionProviderMap.get(sessionId);
        log.info("UnifiedVoiceSessionManager: Found provider for session {}: {}", sessionId, provider);
        
        VoiceSessionService service = provider != null ? getVoiceSessionService(provider) : null;
        log.info("UnifiedVoiceSessionManager: Retrieved service: {} for provider: {}", 
                service != null ? service.getClass().getSimpleName() : "null", provider);
        
        return service;
    }
    
    /**
     * 根据提供商名称获取服务实例
     */
    private VoiceSessionService getVoiceSessionService(String provider) {
        log.info("UnifiedVoiceSessionManager: Getting voice service for provider: {}", provider);
        if (provider == null) return null;
        VoiceSessionService service = providerServiceMap.get(provider.toLowerCase());
        if (service == null) {
            log.warn("Unsupported voice service provider: {}", provider);
        }
        return service;
    }
    
    /**
     * 创建包装的回调，添加统一管理功能和MRCP事件发送
     */
    private VoiceSessionService.SessionCallback createWrappedCallback(String sessionId, 
                                                                     VoiceSessionService.SessionCallback originalCallback,
                                                                     String provider,
                                                                     MrcpRequest mrcpRequest) {
        return new VoiceSessionService.SessionCallback() {
            @Override
            public void onIntermediateResult(String sessionId, RecognitionResult result) {
                log.debug("Intermediate result from {} for session {}: {}", provider, sessionId, result.getText());
                if (originalCallback != null) {
                    originalCallback.onIntermediateResult(sessionId, result);
                }
            }

            @Override
            public void onFinalResult(String sessionId, RecognitionResult result) {
                log.info("Final result from {} for session {}: {}", provider, sessionId, result.getText());
                
                // 发送MRCP RECOGNITION-COMPLETE事件
                if (mrcpRequest != null) {
                    try {
                        // 创建NLSML格式的识别结果
                        String nlsmlResult = formatRecognitionResultAsNlsml(result, sessionId);
                        
                        // 创建RECOGNITION-COMPLETE事件
                        MrcpEvent event = MrcpMessageFactory.createRecognitionCompleteEvent(mrcpRequest, nlsmlResult);
                        
                        // 发送事件
                        boolean sent = mrcpMessageSender.sendMessage(sessionId, event);
                        if (sent) {
                            log.info("RECOGNITION-COMPLETE event sent for session {}: {}", sessionId, result.getText());
                        } else {
                            log.warn("Failed to send RECOGNITION-COMPLETE event for session {}", sessionId);
                        }
                    } catch (Exception e) {
                        log.error("Error sending RECOGNITION-COMPLETE event for session {}: {}", sessionId, e.getMessage(), e);
                    }
                }
                
                // 调用原始回调
                if (originalCallback != null) {
                    originalCallback.onFinalResult(sessionId, result);
                }
            }

            @Override
            public void onError(String sessionId, Exception error) {
                log.error("Error from {} for session {}: {}", provider, sessionId, error.getMessage());
                
                // 发送MRCP RECOGNITION-COMPLETE错误事件
                if (mrcpRequest != null) {
                    try {
                        // 创建RECOGNITION-COMPLETE错误事件
                        MrcpEvent event = MrcpMessageFactory.createRecognitionCompleteErrorEvent(mrcpRequest, error.getMessage());
                        
                        // 发送事件
                        boolean sent = mrcpMessageSender.sendMessage(sessionId, event);
                        if (sent) {
                            log.info("RECOGNITION-COMPLETE error event sent for session {}: {}", sessionId, error.getMessage());
                        } else {
                            log.warn("Failed to send RECOGNITION-COMPLETE error event for session {}", sessionId);
                        }
                    } catch (Exception e) {
                        log.error("Error sending RECOGNITION-COMPLETE error event for session {}: {}", sessionId, e.getMessage(), e);
                    }
                }
                
                // 调用原始回调
                if (originalCallback != null) {
                    originalCallback.onError(sessionId, error);
                }
            }

            @Override
            public void onStateChanged(String sessionId, VoiceSessionService.SessionState oldState, VoiceSessionService.SessionState newState) {
                log.debug("State changed from {} for session {}: {} -> {}", provider, sessionId, oldState, newState);
                
                // 如果会话结束，自动清理映射
                if (newState == VoiceSessionService.SessionState.STOPPED || 
                    newState == VoiceSessionService.SessionState.ERROR) {
                    
                    // 延迟清理，给业务逻辑处理时间
                    CompletableFuture.delayedExecutor(5, java.util.concurrent.TimeUnit.SECONDS)
                        .execute(() -> {
                            if (sessionProviderMap.get(sessionId) != null) {
                                log.debug("Auto-cleaning session mapping for completed session: {}", sessionId);
                                sessionProviderMap.remove(sessionId);
                            }
                        });
                }
                
                if (originalCallback != null) {
                    originalCallback.onStateChanged(sessionId, oldState, newState);
                }
            }
        };
    }
    
    /**
     * 将识别结果格式化为NLSML格式
     * 参考MRCP RFC 6787标准，根据DEFINE-GRAMMAR中定义的语法格式生成
     */
    private String formatRecognitionResultAsNlsml(RecognitionResult result, String sessionId) {
        if (result == null || result.getText() == null || result.getText().trim().isEmpty()) {
            return createEmptyNlsmlResult();
        }
        
        // 获取置信度分数，默认为0.5
        Double confidenceValue = result.getConfidence();
        double confidence = confidenceValue != null ? confidenceValue.doubleValue() : 0.5;
        
        return generateNlsmlFromGrammar(result.getText(), confidence, sessionId);
    }
    
    /**
     * 根据语法定义生成NLSML结果
     */
    private String generateNlsmlFromGrammar(String recognizedText, double confidence, String sessionId) {
        // 获取存储的语法定义
        String grammarContent = mrcpMessageHandler.getGrammar(sessionId);
        
        StringBuilder nlsml = new StringBuilder();
        nlsml.append("<?xml version=\"1.0\"?>\n");
        nlsml.append("<result>\n");
        
        if (grammarContent != null && !grammarContent.trim().isEmpty()) {
            // 解析语法定义并生成相应的NLSML
            String instance = generateInstanceFromGrammar(recognizedText, grammarContent);
            
            nlsml.append("  <interpretation confidence=\"").append(String.format("%.2f", confidence)).append("\">\n");
            nlsml.append("    <instance>").append(instance).append("</instance>\n");
            nlsml.append("    <input mode=\"speech\">").append(escapeXml(recognizedText)).append("</input>\n");
            nlsml.append("  </interpretation>\n");
        } else {
            // 如果没有语法定义，使用简单格式
            nlsml.append("  <interpretation confidence=\"").append(String.format("%.2f", confidence)).append("\">\n");
            nlsml.append("    <instance>\n");
            nlsml.append("      <text>").append(escapeXml(recognizedText)).append("</text>\n");
            nlsml.append("    </instance>\n");
            nlsml.append("    <input mode=\"speech\">").append(escapeXml(recognizedText)).append("</input>\n");
            nlsml.append("  </interpretation>\n");
        }
        
        nlsml.append("</result>");
        return nlsml.toString();
    }
    
    /**
     * 根据语法定义生成实例数据
     * 解析SRGS语法并根据识别结果生成相应的语义结构
     */
    private String generateInstanceFromGrammar(String recognizedText, String grammarContent) {
        try {
            // 解析语法中的规则和标签
            if (grammarContent.contains("<tag>") && grammarContent.contains("</tag>")) {
                // 包含语义标签的语法
                return generateSemanticInstance(recognizedText, grammarContent);
            } else if (grammarContent.contains("<item>")) {
                // 简单的项目列表语法
                return generateSimpleInstance(recognizedText, grammarContent);
            } else {
                // 默认文本格式
                return "<text>" + escapeXml(recognizedText) + "</text>";
            }
        } catch (Exception e) {
            log.warn("Error parsing grammar for semantic interpretation: {}", e.getMessage());
            // 降级为简单文本格式
            return "<text>" + escapeXml(recognizedText) + "</text>";
        }
    }
    
    /**
     * 生成语义实例（包含tag的语法）
     */
    private String generateSemanticInstance(String recognizedText, String grammarContent) {
        StringBuilder instance = new StringBuilder();
        
        // 简单的语义解析 - 在实际应用中应该更复杂
        if (recognizedText.matches("\\d+")) {
            // 数字
            instance.append("<number>").append(recognizedText).append("</number>");
        } else if (recognizedText.toLowerCase().contains("是") || recognizedText.toLowerCase().contains("确认")) {
            // 确认命令
            instance.append("<confirm>true</confirm>");
            instance.append("<action>confirm</action>");
        } else if (recognizedText.toLowerCase().contains("否") || recognizedText.toLowerCase().contains("取消")) {
            // 取消命令
            instance.append("<confirm>false</confirm>");
            instance.append("<action>cancel</action>");
        } else {
            // 默认处理
            instance.append("<command>").append(escapeXml(recognizedText)).append("</command>");
        }
        
        return instance.toString();
    }
    
    /**
     * 生成简单实例（item列表语法）
     */
    private String generateSimpleInstance(String recognizedText, String grammarContent) {
        // 从语法中提取可能的选项
        return "<selected>" + escapeXml(recognizedText) + "</selected>";
    }
    
    /**
     * 创建空的NLSML结果（当没有识别到内容时）
     */
    private String createEmptyNlsmlResult() {
        StringBuilder nlsml = new StringBuilder();
        nlsml.append("<?xml version=\"1.0\"?>\n");
        nlsml.append("<result grammar=\"session:grammar\">\n");
        nlsml.append("  <noinput/>\n");
        nlsml.append("</result>");
        
        return nlsml.toString();
    }
    
    /**
     * XML转义特殊字符
     */
    private String escapeXml(String text) {
        if (text == null) return "";
        return text.replace("&", "&amp;")
                  .replace("<", "&lt;")
                  .replace(">", "&gt;")
                  .replace("\"", "&quot;")
                  .replace("'", "&apos;");
    }
    
    /**
     * 获取服务统计信息
     */
    public String getServiceInfo() {
        StringBuilder info = new StringBuilder();
        info.append("UnifiedVoiceSessionManager{");
        info.append("defaultProvider=").append(engineConfig.getDefaultProvider());
        info.append(", totalSessions=").append(sessionProviderMap.size());
        info.append(", activeSessions=").append(getTotalActiveSessionCount());
        
        // 汇总每个提供商的活跃会话
        providerServiceMap.forEach((name, svc) -> {
            try {
                info.append(", ").append(name).append("Active=").append(svc.getActiveSessionCount());
            } catch (Exception ignored) {}
        });
        
        info.append("}");
        return info.toString();
    }
    
    /**
     * 记录所有会话信息（用于调试）
     */
    public void logSessionInfo() {
        log.info("Unified session manager - total sessions: {}, active: {}", 
            sessionProviderMap.size(), getTotalActiveSessionCount());
        
        sessionProviderMap.forEach((sessionId, provider) -> {
            VoiceSessionService.SessionState state = getSessionState(sessionId);
            log.info("  Session: {}, provider: {}, state: {}", sessionId, provider, state);
        });
    }
}
